package model.data;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.UnknownHostException;

import signals.UserNotifications;
import signals.UserStatus;
import signals.Wizz;
import cs.remoteapp.FileAnswer;
import cs.remoteapp.FileRequest;
import cs.remoteapp.Goodbye;
import cs.remoteapp.Hello;
import cs.remoteapp.Message;
import cs.remoteapp.TextMessage;
import exceptions.MessageCreationException;

/**
 
 */
/**@author SIAGO HAPPI Christelle
 * MessagesFactory : Used to manage the creation of messages
 */
public class MessagesFactory {

	private MessagesFactory() {}
	
	/**
	 * @param username : the login of the user
	 * @param isBroadcast : indicates if the hello message is sent in broadcast
	 * @return byte[] 
	 * @throws MessageCreationException
	 */
	/** 
	 * Returns a byte [] containing the Hello application
	 */
	public static byte[] getHello(String username, boolean isBroadcast) throws MessageCreationException {
		Hello myHello;
		
		try {
			
			myHello = new Hello(username);
			myHello.setBroadcast(isBroadcast);
			return createByte(myHello).toByteArray();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new MessageCreationException("Can not find your hostname");
			
		} catch (IOException e) {
			e.printStackTrace();
			throw new MessageCreationException("can not create the byte[]");
		}
		
	}
	
	public static byte[] getTextMessage(String username, String text) throws MessageCreationException {
		TextMessage myMessage;
		
		try {
			
			myMessage = new TextMessage(username, text);
			return createByte(myMessage).toByteArray();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new MessageCreationException("Can not find your hostname");
			
		} catch (IOException e) {
			e.printStackTrace();
			throw new MessageCreationException("can not create the byte[]");
		}
		
	}
	
	
	/**
	 * Returns the byte [] message Bye
	 * @param username
	 * @return the byte [] message Bye
	 * @throws MessageCreationException
	 */
	public static byte[] getBye(String username) throws MessageCreationException {
		Goodbye myBye;
		
		try {
			myBye = new Goodbye(username);
			return createByte(myBye).toByteArray();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new MessageCreationException("Can not find your hostname");
		}
		 catch (IOException e) {
			e.printStackTrace();
			throw new MessageCreationException("can not create the byte[]");
		}
		
	}
	

	
	/**
	 * @param myArray 
	 * @return Message
	 * @throws MessageCreationException
	 */
	/**
	 * Returns the corresponding byte in the message [] as argument
	 */
	public static Message getMessage(byte[] myArray) throws MessageCreationException {
		ByteArrayInputStream byteAIS;
		ObjectInputStream ois;
		
		try {
			
			byteAIS = new ByteArrayInputStream(myArray);
			ois = new ObjectInputStream(byteAIS);
			Object monObject = ois.readObject();
			
			if (monObject instanceof Message) {
				return (Message)monObject;
			}
			else {
				throw new MessageCreationException("Byte [] does not correspond to a known post");
			}
			
		} catch (IOException e) {
			e.printStackTrace();
			throw new MessageCreationException("Unable to create the message");
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new MessageCreationException("Unable to create the message");
		} 
			
	}
	
	/**
	 * Returns the byte [] message FileRequest
	 * @param username
	 * @return
	 * @throws MessageCreationException
	 */
	public static byte[] getFileRequest(String username, String fileName, long fileSize) throws MessageCreationException {
		FileRequest myFileRequest;
		
		try {
			myFileRequest = new FileRequest(username, fileName, fileSize);
			return createByte(myFileRequest).toByteArray();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new MessageCreationException("Impossible de determiner votre nom d'hote");
		}
		 catch (IOException e) {
			e.printStackTrace();
			throw new MessageCreationException("can not create the byte[]");
		}
		
	}
	
	/**
	 * Returns the byte []  message FileAnswer
	 * @param username
	 * @return
	 * @throws MessageCreationException
	 */
	public static byte[] getFileFileAnswer(String username, String fileName, boolean answer) throws MessageCreationException {
		FileAnswer myFileAnswer;
		
		try {
			myFileAnswer = new FileAnswer(username, fileName, answer);
			return createByte(myFileAnswer).toByteArray();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new MessageCreationException("Can not find your hostname");
		}
		 catch (IOException e) {
			e.printStackTrace();
			throw new MessageCreationException("can not create the byte[]");
		}
		
	}
	   /**
	    * Return the byte [] message Wizz
	    * @param username
	    * @throws MessageCreationException
	    * @return byte[]
	    */
	    public static byte[] getWizz(String username) throws MessageCreationException {
	        Wizz myWizz;
	        try {
	            myWizz = new Wizz(username);
	            return createByte(myWizz).toByteArray();       
	        } catch (UnknownHostException e) {
	        	throw new MessageCreationException("Can not find your hostname");
	        }
	        catch (IOException e) {
	        	throw new MessageCreationException("can not create the byte[]");
	        }  
	    }
	    /**
	     * return the byte[] message UserStatus 
	     * @param  login     Login of the local user
	     * @param  show      Status of the user to notify
	     * @throws MessageCreationException
	     * @return byte[]
	     */
	     public static byte[] getUserStatus(String login, Status show) throws MessageCreationException {
	    	 UserStatus myStatus;
	         try {
	             myStatus = new UserStatus(login,show);
	             return createByte(myStatus).toByteArray();       
	         } catch (UnknownHostException e) {
	        	 throw new MessageCreationException("Can not find your hostname");
	         }
	         catch (IOException e) {
	        	 throw new MessageCreationException("can not create the byte[]");
	         }     
	     }
	     
	     /**
	      * Return the byte[] message User Notification 
	      * @param login Login of the local user
	      * @param isWriting   <code>true</code> if the user is writing
	      *                  <code>false</code> otherwise
	      * @throws MessageCreationException
	      * @return byte[]
	      */
	      public static byte[] getUserNotificiation(String login,boolean isWriting) throws MessageCreationException {
	    	  UserNotifications myUserNotificiation;
	          try {
	        	  myUserNotificiation = new UserNotifications(login,isWriting);
	              return createByte(myUserNotificiation).toByteArray();       
	          } catch (UnknownHostException e) {
	        	  throw new MessageCreationException("Can not find your hostname");
	          }
	          catch (IOException e) {
	        	  throw new MessageCreationException("can not create the byte[]");
	          }     
	      }
	
	/**
	 * @param myMessage
	 * @return ByteArrayOutputStream
	 * @throws IOException
	 */
	/**
	 * Returns a ByteArrayOutputStream containing the message my Message
	 */
	private static ByteArrayOutputStream createByte(Message myMessage) throws IOException {
		ByteArrayOutputStream byteAOS;
		ObjectOutputStream oos;
		
		byteAOS = new ByteArrayOutputStream();
		
		oos = new ObjectOutputStream(byteAOS);
		oos.writeObject(myMessage);
		oos.flush();
		oos.close();
		
		return byteAOS;
	}
	
}
